<template>
    <div class="app-container">
        <el-button type="primary" link :icon="Back" @click="back">返回</el-button>
        <div class="highspeed-scanner-container flex" v-loading="initLoading">
            <el-card>
                <div class="flexC" style="justify-content: space-between;">
                    <p class="title flexC">
                        <el-icon style="color: var(--el-color-primary);"><View /></el-icon>
                        <span>实时预览</span>                        
                    </p>
                </div>
                <div class="fileView">
                    <div class="emtry-view flexCC" v-if="!initStatus">
                        <div class="emtry-content">
                            <el-icon><Film /></el-icon>
                            <p>请先启动高拍仪</p>
                        </div>
                    </div>
                    <canvas id="mframe"  width="640" height="480" ></canvas>
                </div>
                <div class="foot-btn" align="center">
                    <el-checkbox v-model="IsA4" style="float: left;" label="单页拍摄" :true-value="true" :false-value="false"  @change="changeA4"  />
                    <el-button type="primary" :icon="VideoCameraFilled" v-if="!initStatus" @click="CZUR_ID_OpenDevice">启动高拍仪</el-button>
                    <template v-else>
                        <el-button type="primary" :icon="CameraFilled" :loading="GrabLoading" :disabled="submitLoad" @click="CZUR_ID_GrabImage">拍照</el-button>
                        <el-button type="danger" :icon="Failed" @click="CZUR_ID_CloseDevice">关闭摄像头</el-button>
                    </template>
                </div>
            </el-card>
            <el-card>
                <div class="flexC" style="justify-content: space-between;margin-bottom:20px;">
                    <p class="title" style="margin-bottom: 0;">
                        结果预览
                    </p>
                    <el-button type="primary" :icon="UploadFilled" @click="handleSubmit" :loading="submitLoad" :disabled="imagesList.length === 0">提交</el-button>
                </div>
                <div class="ImgView-container">
                    <div class="ImgView-emtry flexCC" v-if="imagesList.length === 0">
                        <div class="emtry-content">
                            <p>请先拍照</p>
                        </div>
                    </div>
                    <viewer :images="imagesList" class="Viewer-container" v-if="imagesList.length != 0">
                        <template v-for="(image, index) in imagesList" :key="index">
                            <div class="viewer-item">
                                <el-icon @click="handleRemove(index)"><Close /></el-icon>
                                <img :src="image.base64" class="PreviewImg" style="width: 80px;height: 80px;" />
                            </div>
                        </template>
                    </viewer>
                    <!--<viewer :images="imageList" :options="viewerOptions"> -->
                </div>
            </el-card>
        </div>
    </div>
</template>

<script setup>
import { Back, VideoCameraFilled, CameraFilled, Failed, Film, UploadFilled, Close } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { nextTick, onMounted, onUnmounted, ref } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import config  from "@/config/default-settings";
import { AppConfig } from "@/api/user";
import { projectCamera } from "@/api/project";

const router = useRouter();
const route = useRoute();
const initLoading = ref(false);
const submitLoad = ref(false);

// 文件保存路径
const savePath = ref(null);
// 是否 进行 A4 拍摄
const IsA4 = ref(true);

// 拍照预览图片
const imagesList = ref([]);
const GrabLoading = ref(false);
// 合成pdf文件名
const pdfName = ref("");

var m_cav_frame;
var m_ctx_frame;
var m_img_frame = new Image();

//记录主头处理方式
var m_process_type = 0;
//记录副头处理方式，0(不处理)、1(手动框选裁剪)、2(人脸对比)
var s_process_type = 0;

//标记当前是否按下鼠标左键
var is_down_m = false;
//记录主头手动框选裁剪得矩形框
var m_left;
var m_top;
var m_right;
var m_bottom;

//标记当前是否按下鼠标左键
var is_down_s = false;
//记录副头需要绘制的矩形框坐标
// var s_left   = 0.2 * s_cav_frame.width;
// var s_top    = 0.2 * s_cav_frame.height;
// var s_right  = 0.8 * s_cav_frame.width;
// var s_bottom = 0.8 * s_cav_frame.height;

//记录主头自动裁剪边框坐标
var m_x1 = 0, m_y1 = 0, m_x2 = 0, m_y2 = 0, m_x3 = 0, m_y3 = 0, m_x4 = 0, m_y4 = 0;

//记录副头人脸检测区域坐标
var s_x1 = 0, s_y1 = 0, s_x2 = 0, s_y2 = 0, s_x3 = 0, s_y3 = 0, s_x4 = 0, s_y4 = 0;

//是否绘制主头视频画面
var is_draw_m_frame = false;
//是否绘制副头视频画面
var is_draw_s_frame = false;
//
var is_draw_ir_frame = false;

//主头通道信息
var ws_mc = ref(null);
var mc_svc_port = 9999;
var mc_svc_connect = ref(false);

//副头通道信息
var ws_sc = null;
var sc_svc_port = 10001;
var sc_svc_connect = false;

//红外摄像头通道信息
var ws_ir = null;
var ir_svc_port = 10002;
var ir_svc_connect = false;

//指令通道信息
var ws_cmd = ref(null);
var cmd_svc_port = 25014;
var cmd_svc_connect = ref(false);

//记录录像时摄像头序号
var record_camera_index=0;

//记录身份证头像数据
var head_base64 = null;

window.onbeforeunload = function (e) {
    ws_mc.value.close();
    // ws_sc.close();
    // ws_ir.close();
    ws_cmd.value.close();
    return 1;
}

const changeA4 = ()=>{
    //     // 设置 自动剪裁黑边
        CZUR_ID_SetProcessType()
    //     // 设置A4拍摄幅面
        CZUR_ID_SetA4Wide();
}

// 初始化 连接状态 
const initStatus = ref(false);
onMounted(() => {
    initHighSpeedScanner();
    getHighConfig();
    nextTick(() => {
        m_cav_frame = document.getElementById("mframe")
        m_ctx_frame = m_cav_frame.getContext("2d")
        m_left = 0.2 * m_cav_frame.width;
		m_top = 0.2 * m_cav_frame.height;
		m_right = 0.8 * m_cav_frame.width;
		m_bottom = 0.8 * m_cav_frame.height;
    })
});
const getHighConfig =async ()=>{
    let result = await AppConfig();
    if(result && result.data){
        savePath.value = result.data.fileCameraDir;
    }
}
const m_cav_frame_handle = () =>{
    m_cav_frame.onmousedown = function (e) {
        if (is_draw_m_frame) {
            if (1 == m_process_type) {
                is_down_m = true;
                m_left = e.offsetX;
                m_top = e.offsetY;
            }
        }
    }

    m_cav_frame.onmouseup = function (e) {
        if (is_draw_m_frame) {
            if (is_down_m && 1 == m_process_type) {
                is_down_m = false;

                //设置手动框选裁剪，格式：{"id": 19, "type": 纸张处理方式, "left": left位置, "top": top位置, "right": right位置, "bottom": bottom位置}
                var left = 1.0 * m_left / m_cav_frame.width;
                var top = 1.0 * m_top / m_cav_frame.height;
                var right = 1.0 * m_right / m_cav_frame.width;
                var bottom = 1.0 * m_bottom / m_cav_frame.height;

                var cmd = '{\"id\": 19, \"type\": 1, \"left\": ' + left + ', \"top\": ' + top + ', \"right\": ' + right + ', \"bottom\": ' + bottom + '}';
                ws_cmd.send(cmd);
            }
        }
    }

    m_cav_frame.onmousemove = function (e) {
        if (is_draw_m_frame) {
            if (is_down_m && 1 == m_process_type) {
                m_right = e.offsetX;
                m_bottom = e.offsetY;
                m_ctx_frame.drawImage(m_img_frame, 0, 0, m_cav_frame.width, m_cav_frame.height);
                DrawRect(0);
            }
        }
    }
}
const initHighSpeedScanner = async () => {
    // initLoading.value = true;
    await connect_cmd_svc();
    // await connect_mc_svc();
    // await CZUR_ID_Initialize();
};
// 连接指令服务器
const connect_cmd_svc = async () => {
   if(cmd_svc_connect.value == true){
		console.log("已连接指令服务器");
		return;
	}
	var url1 = "wss://127.0.0.1:" + cmd_svc_port + "/";
	var url2 = "ws://127.0.0.1:" + cmd_svc_port + "/";
	var url = "";
	url = url || ('https:' == document.location.protocol ? url1 : url2);
	if ('WebSocket' in window){
		ws_cmd.value = new WebSocket(url);
	} else if('MozWebSocket' in window){
		ws_cmd.value = new MozWebSocket(url);
	} else	{
		ElMessage.error("浏览器不支持WebSocket");
		return;
	}
    await cmdWebSocketEvent(); 
    
} 
const cmdWebSocketEvent = () => {
    ws_cmd.value.onopen = async function(){
		cmd_svc_connect.value = true;
		console.log("成功连接指令服务器");
        await connect_mc_svc();
	}

	ws_cmd.value.onclose = function(){
		cmd_svc_connect.value = false;
		console.log("与指令服务器连接中断");
	}

    ws_cmd.value.onmessage = function (e) {
        var jsonObj = window.JSON.parse(e.data);
        switch (jsonObj.id) {
            //处理json数据包失败反馈
            case 0: {
                var error = jsonObj.error;

                switch (error) {
                    case 3: {
                        console.log("系统内存不足，无法处理当前指令");
                    } break;

                    case 5: {
                        console.log("无效的json指令格式");
                    } break
                }
            }
                break;
            //初始化CZURPlugin环境反馈
            case 2: {
                CZUR_ID_Initialize_Response(jsonObj);
            }
                break;

            //清除CZURPlugin环境反馈
            case 4: {
                m_process_type = 0;
                is_draw_m_frame = false;
                initStatus.value = false;
                m_ctx_frame.fillStyle = "#000000";
                m_ctx_frame.beginPath();
                m_ctx_frame.fillRect(0, 0, m_cav_frame.width, m_cav_frame.height);
                m_ctx_frame.closePath();
            }
                break;
            case 331: {
				CZUR_ID_DataReady_Response(jsonObj);
			}
                break;
            //打开设备反馈
            case 10: {
                CZUR_ID_OpenDevice_Response(jsonObj);
            }
                break;
            //自动裁边反馈消息，用于绘制矩形框
            case 56: {
                if (2 == m_process_type) {
                    m_x1 = m_cav_frame.width * jsonObj.x1;
                    m_y1 = m_cav_frame.height * jsonObj.y1;
                    m_x2 = m_cav_frame.width * jsonObj.x2;
                    m_y2 = m_cav_frame.height * jsonObj.y2;
                    m_x3 = m_cav_frame.width * jsonObj.x3;
                    m_y3 = m_cav_frame.height * jsonObj.y3;
                    m_x4 = m_cav_frame.width * jsonObj.x4;
                    m_y4 = m_cav_frame.height * jsonObj.y4;
                }
            }
                break;
       
                break;
            //设置主头纸张处理方式反馈
            case 20: {
                CZUR_ID_SetProcessType_Response(jsonObj);
            }
                break;
            //设置拍摄A4幅面反馈
            case 111: {
                CZUR_ID_SetA4Wide_Response(jsonObj);
            }
                break;
            //关闭设备反馈
            case 12: {
                CZUR_ID_CloseDevice_Response(jsonObj);
            }
                break;
            //拍照保存图像文件反馈
            case 14: {
                CZUR_ID_GrabImage_Response(jsonObj);
            }
                break;
            //检测到翻页或硬拍得反馈
            case 25: {
                var state = jsonObj.state;

                switch (state) {
                    case 1: {
                        console.log("已检测到硬拍工作");
                    } break;

                    case 2: {
                        console.log("已检测到翻页工作");
                    } break;
                }
                //触发拍照
                CZUR_ID_GrabImage();
            }
                break;
            //删除本地文件反馈
            case 41: {
                CZUR_ID_DeleteFile_Response(jsonObj);
            }
                break;
            //多文件合成PDF反馈
            case 160: {
                CZUR_ID_ImageToPDFEx_Response(jsonObj);
            }
                break;
            //图像处理结果通知
            case 301: {
                CZUR_ID_IMAGE(jsonObj);
            }
                break;
        }

    }

}

// 连接主头服务器
const  connect_mc_svc = async () => {
    if (mc_svc_connect.value == true) {
        console.log("已连接主头服务器");
        return;
    }

    var url1 = "wss://127.0.0.1:" + mc_svc_port + "/";
    var url2 = "ws://127.0.0.1:" + mc_svc_port + "/";
    var url = "";

    url = url || ('https:' == document.location.protocol ? url1 : url2);

    if ('WebSocket' in window) {
        ws_mc.value = new WebSocket(url);
    }
    else if ('MozWebSocket' in window) {
        ws_mc.value = new MozWebSocket(url);
    }
    else {
        ElMessage.error("浏览器不支持WebSocket");
    }
    await mcWebSocketEvent();
}
const mcWebSocketEvent = () => {
    ws_mc.value.onopen = async function () {
        mc_svc_connect.value = true;
        console.log("成功连接主头服务器");
        await CZUR_ID_Initialize();
    }

    ws_mc.value.onclose = function () {
        is_draw_m_frame = false;
        mc_svc_connect.value = false;
        console.log("与主头服务器连接中断");
    }

    ws_mc.value.onmessage = function (e) {
        // console.log(e,is_draw_m_frame);
        if (is_draw_m_frame) {
            if(!initStatus.value){
                initStatus.value = true;
            }
            m_img_frame.crossOrigin = 'anonymous';
            m_img_frame.src = 'data:image/jpeg;base64,' + e.data;

            m_img_frame.onload = function (e) {
                m_ctx_frame.drawImage(m_img_frame, 0, 0, m_cav_frame.width, m_cav_frame.height);
                if (1 == m_process_type) {
                    DrawRect(0);
                }else if (2 == m_process_type) {
                    DrawMLine();
                } else if(4 == m_process_type ){
                    DrawPageLine();
                }
            }
        }
    }
}


//初始化CZURPlugin环境，格式: {"id": 1, "license": "授权码"}
const CZUR_ID_Initialize = () => {
    var jsonMsg = {
        id: 1,
        license: config.CZUR_higtKey
    };
    ws_cmd.value.send(JSON.stringify(jsonMsg));
    
}

//设置主头纸张处理方式，格式：{"id": 19, "type": 处理方式, "left": left位置, "top": top位置, "right": right位置, "bottom": bottom位置}
const CZUR_ID_SetProcessType = ()=> {
    m_process_type = IsA4.value ? 2 : 4; // 2 自动裁剪黑边 12 展平拆分左右两页
   //计算区域占据显示窗口的百分比
    var left = 1.0 * m_left / m_cav_frame.width;
    var top = 1.0 * m_top / m_cav_frame.height;
    var right = 1.0 * m_right / m_cav_frame.width;
    var bottom = 1.0 * m_bottom / m_cav_frame.height;

    var cmd = '{\"id\": 19, \"type\": ' + m_process_type + ', \"left\": ' + left + ', \"top\": ' + top + ', \"right\": ' + right + ', \"bottom\": ' + bottom + '}';
    ws_cmd.value.send(cmd); 
}

//设置A4拍摄幅面，格式：{"id": 110, "on": 0/1}
const CZUR_ID_SetA4Wide  = () => {
    
    var on = 0;
    var jsonMsg = {
        id: 110,
        on: IsA4.value ? 1 : 0
    };
    ws_cmd.value.send(JSON.stringify(jsonMsg));
    
}

//关闭设备，格式: {"id": 11, "index": 摄像头序号}
const CZUR_ID_CloseDevice = () => {
    //摄像头序号
    var jsonMsg = {
        id: 11,
        index: 0
    };
    ws_cmd.value.send(JSON.stringify(jsonMsg));
}

//打开设备，格式：{"id": 9, "index": 摄像头序号}
const CZUR_ID_OpenDevice = () => {
    //摄像头分辨率
    var width, height;

    //摄像头序号
    var jsonMsg = {
        id: 9,
        index: 0
    };
    ws_cmd.value.send(JSON.stringify(jsonMsg));
    // ws_cmd.send(JSON.stringify({
    //     id: 26,
    //     index: 0,
    //     width: 3264,
    //     height: 2448
    // }));
}
const CZUR_ID_DataReady_Response = () =>{
    // setTimeout(() => {
    // if(IsA4.value){
    //     // 设置 自动剪裁黑边
        CZUR_ID_SetProcessType()
    //     // 设置A4拍摄幅面
        CZUR_ID_SetA4Wide();
    // }
    // }, 500);
    console.log("视频帧准备就绪")
}
//打开设备反馈，格式：{"id": 10, "error": 错误代码}
const CZUR_ID_OpenDevice_Response = (jsonObj) => {
    var error = jsonObj.error;
    switch (error) {
        case 0: {
            var index = 0;
            console.log("222222");
            
            if (0 == index) {
                is_draw_m_frame = true;
            } else if (2 == index) {
                is_draw_ir_frame = true;
            } else {
                is_draw_s_frame = true;
            }
            initStatus.value = true;
            console.log("打开摄像头成功");
        } break;

        case 1: {
            console.log("打开摄像头失败 异常错误");
        } break;

        case 8: {
            console.log("CZURPlugin环境未初始化 设备不支持");
        } break;

        case 10: {
            
            console.log("设备不支持副摄像头");
        } break;

        case 11: {
            console.log("无效的摄像头序号");
        } break;

        case 12: {
            console.log("摄像头已打开");
        } break;

        case 13: {
            console.log("设备未连接，请将设备连接电脑");
            ElMessage.error("设备未连接，请将设备连接电脑");
        } break;
    }
}
//设置主头纸张处理方式反馈，格式：{"id": 20, "error": 错误代码}
const CZUR_ID_SetProcessType_Response = (jsonObj) => {
    var error = jsonObj.error;

    switch (error) {
        case 0: {
            console.log("设置纸张处理方式成功");
        } break;

        case 4: {
            console.log("录像期间，无法设置纸张处理方式");
        } break;

        case 8: {
            console.log("CZURPlugin环境未初始化");
            
        } break;

        case 10: {
            console.log("设置不支持当前纸张处理方式");
        } break;

        case 14: {
            console.log("摄像头尚未打开，无法纸张处理方式");
        } break;

        case 23: {
            console.log("无效的纸张处理方式");
        } break;

        case 49: {
            console.log("无效的手动框选裁剪区域");
        } break;
    }
}

//设置A4拍摄幅面反馈，格式：{"id": 111, "error": 错误代码}
const CZUR_ID_SetA4Wide_Response = (jsonObj) => {
    var error = jsonObj.error;
    switch (error) {
        case 0: {
            console.log("设置拍摄幅面成功");
        } break;

        case 4: {
            console.log("正在录像或人脸识别，无法设置");            
        } break;

        case 8: {
            console.log("CZURPlugin环境未初始化");
        } break;

        case 10: {
            console.log("设备不支持，无法设置A4拍摄幅面");
        } break;

        case 14: {
            console.log("主摄像头尚未开启，无法设置");
        } break;
    }
}

//拍照保存文件，格式: {"id": 13, "index": 摄像头序号, "file": "图像文件名称", "dpi": DPI, "color": 颜色模式, "round": 圆角留白, "adjust": 方向转正, "bcr": 条码识别, "bpd": 空白页检测, "quality": JPG压缩质量, "compress": TIFF压缩方式}
const CZUR_ID_GrabImage = () => {
    GrabLoading.value = true;
    //摄像头序号
    var index = 0;

    //图像文件名称
    var filename = savePath.value + new Date().getTime()+''+Math.floor(Math.random()*1000)+'.jpg';

    //DPI
    var dpi = 0;

    //色彩模式
    var color = 1;

    //圆角留白
    var round = 0;
   

    //方向调整
    var adjust = 1;
   

    //识别条码
    var bcr = 0;
 
    //空白页检测
    var bpd = 0;

    //JPG压缩质量
    var quality = 100;

    //TIFF压缩方式
    var compress = 1;

    var jsonMsg = {
        id: 13,
        index: index,
        file: filename,
        dpi: dpi,
        color: color,
        round: round,
        adjust: adjust,
        bcr: bcr,
        bpd: bpd,
        quality: quality,
        compress: compress
    };
    ws_cmd.value.send(JSON.stringify(jsonMsg));
}

//拍照保存文件反馈，格式: {"id": 14, "error": 错误代码}
const CZUR_ID_GrabImage_Response = (jsonObj) => {
    var error = jsonObj.error;

    switch (error) {
        case 0: {
            console.log("拍照成功，图像正在处理，请稍后");
        } break;

        case 1: {
            console.log("异常错误");
        } break;

        case 3: {
            console.log("系统内存不足");
        } break;

        case 4: {
            console.log("录像期间，无法拍照")   ;
        } break;

        case 8: {
            console.log("CZURPlugin环境未初始化");
        } break;

        case 10: {
            console.log("设备不支持某些拍照属性参数设置");
        } break;

        case 11: {
            console.log("无效的摄像头序号");
        } break;

        case 14: {
            ElMessage.error("摄像头尚未打开");
            console.log("摄像头尚未打开");
        } break;

        case 17: {
            console.log("无效的颜色模式");
        } break;

        case 18: {
            console.log("图像保存格式不合法，仅支持JPG、BMP、PNG、PDF、TIFF");
        } break;

        case 19: {
            ElMessage.warning("激光线闪过之后，才可以拍摄下一张");
            console.log("激光线闪过之后，才可以拍摄下一张");
        } break;

        case 20: {
            console.log("非法TIFF压缩方式");
        } break;

        case 21: {
            console.log("无效的JPG压缩质量");
        } break;

        case 43: {
            console.log("字符集转换失败");
        } break;

        case 50: {
            console.log("图像数据尚未准备好，请稍后再试");
        } break;
    }
}

//将处理完毕的图像信息通知给调用者
const CZUR_ID_IMAGE = (jsonObj) => {
    GrabLoading.value = false;
    var error = jsonObj.error;
    switch (error) {
        case 0: {

            if (jsonObj.file1 != "null") {
                console.log("保存图像成功，文件名称为: " + jsonObj.file1);
                let imgs =  {
                    filePath: jsonObj.file1,
                    base64:'data:image/jpeg;base64,' + jsonObj.b641
                }
                imagesList.value.push(imgs);
            }

            if (jsonObj.file2 != "null") {
                console.log("保存图像成功，文件名称为: " + jsonObj.file2);
                let imgs =  {
                    filePath: jsonObj.file2,
                    base64:'data:image/jpeg;base64,' + jsonObj.b642
                }
                imagesList.value.push(imgs);
            }
        } break;

        case 1: {
            ElMessage.error("发生异常错误，无法保存图像");
        } break;

        case 3: {
            ElMessage.error("系统内存不足");
        } break;

        case 36: {
            console.log("保存图像文件失败，请检查路径是否有效");
        } break;

        case 37: {
            console.log("源PDF文档存在密码保存，导致保存图像失败");
        } break;

        case 40: {
            console.log("图像为空白页，不保存文件");
        } break;
    }
}


//关闭设备反馈，格式: {"id": 12, "error": 错误代码}
const CZUR_ID_CloseDevice_Response = (jsonObj) => {
    var error = jsonObj.error;

    switch (error) {
        case 0: {
            is_draw_m_frame = false;
            m_ctx_frame.fillStyle = "#000000";
            m_ctx_frame.beginPath();
            m_ctx_frame.fillRect(0, 0, m_cav_frame.width, m_cav_frame.height);
            m_ctx_frame.closePath();
            console.log("关闭摄像头成功");
            initStatus.value = false;
        } break;

        case 4: {
            txtlog.value = "正在进行录像，无法关闭设备\r\n" + txtlog.value;
        } break;

        case 8: {
            txtlog.value = "CZURPlugin环境未初始化\r\n" + txtlog.value;
        } break;

        case 11: {
            txtlog.value = "无效的摄像头序号\r\n" + txtlog.value;
        } break;

        case 14: {
            txtlog.value = "摄像头未打开\r\n" + txtlog.value;
        } break;
    }
}


const  DrawRect = (index) => {
	//主头区域
    if (index == 0) {
        m_ctx_frame.shadowBlur = 5;
        m_ctx_frame.shadowColor = "rgba(0,0,0,0.5)";
        m_ctx_frame.strokeStyle = "#FF0000";
        m_ctx_frame.lineWidth = 2;
        m_ctx_frame.beginPath();
        m_ctx_frame.rect(m_left, m_top, m_right - m_left, m_bottom - m_top);
        m_ctx_frame.stroke();
    }
}
// A4 需要框
const  DrawMLine = ()=> {
    m_ctx_frame.shadowBlur = 5;
    m_ctx_frame.shadowColor = "rgba(0,0,0,0.5)";
    m_ctx_frame.strokeStyle = "#00FF00";
    m_ctx_frame.lineWidth = 2;
    m_ctx_frame.beginPath();
    m_ctx_frame.moveTo(m_x1, m_y1);
    m_ctx_frame.lineTo(m_x2, m_y2);
    m_ctx_frame.lineTo(m_x3, m_y3);
    m_ctx_frame.lineTo(m_x4, m_y4);
    m_ctx_frame.lineTo(m_x1, m_y1);
    m_ctx_frame.stroke();
}

const  DrawPageLine = ()=> {
    const w = m_cav_frame.width;
    const h = m_cav_frame.height;
    
     // ==== 左右分割线 ====
    m_ctx_frame.strokeStyle = "orange";
    m_ctx_frame.setLineDash([6, 4]); // 虚线
    m_ctx_frame.lineWidth = 3;
    m_ctx_frame.beginPath();
    m_ctx_frame.moveTo(w / 2, 0);
    m_ctx_frame.lineTo(w / 2, h);
    m_ctx_frame.stroke();

    // ==== 左边虚线框 ====
    m_ctx_frame.beginPath();
    m_ctx_frame.moveTo(50, 50);
    m_ctx_frame.bezierCurveTo(w / 4, 20, w / 4, 20, w / 2 - 20, 50); // 上边曲线
    m_ctx_frame.lineTo(w / 2 - 20, h - 50);
    m_ctx_frame.bezierCurveTo(w / 4, h - 20, w / 4, h - 20, 50, h - 50); // 下边曲线
    m_ctx_frame.closePath();
    m_ctx_frame.strokeStyle = "white";
    m_ctx_frame.setLineDash([8, 6]);
    m_ctx_frame.lineWidth = 2;
    m_ctx_frame.stroke();

    // ==== 右边虚线框 ====
    m_ctx_frame.beginPath();
    m_ctx_frame.moveTo(w / 2 + 20, 50);
    m_ctx_frame.bezierCurveTo((3 * w) / 4, 20, (3 * w) / 4, 20, w - 50, 50); // 上边曲线
    m_ctx_frame.lineTo(w - 50, h - 50);
    m_ctx_frame.bezierCurveTo((3 * w) / 4, h - 20, (3 * w) / 4, h - 20, w / 2 + 20, h - 50); // 下边曲线
    m_ctx_frame.closePath();
    m_ctx_frame.stroke();

    // ==== L / R 标记 ====
    m_ctx_frame.fillStyle = "blue";
    m_ctx_frame.font = "40px Arial";
    m_ctx_frame.fillText("L", w / 4 - 20, h / 2);
    m_ctx_frame.fillText("R", (3 * w) / 4 - 20, h / 2);
}
const handleRemove = (index) => {
    CZUR_ID_DeleteFile(imagesList.value[index].filePath)
    imagesList.value.splice(index, 1);

}
//删除本地文件，格式： {"id": 40, "file": "文件名称"}
const CZUR_ID_DeleteFile = (filePath) => {
    var jsonMsg = {
        id: 40,
        file: filePath
    };
    //调用指令服务器的websocket对象发送这个数据包
    ws_cmd.value.send(JSON.stringify(jsonMsg));
}
//删除本地文件反馈，格式： {"id": 41, "error": 错误代码}
const CZUR_ID_DeleteFile_Response = (jsonObj) => {
    var error = jsonObj.error;

    switch (error) {
        case 0: {
            console.log("删除本地文件成功");
        } break;

        case 1: {
            console.log("删除本地文件发生异常错误");
        } break;

        case 8: {
            console.log("CZURPlugin环境未初始化");
        } break;

        case 43: {
            console.log("字符集转换失败");
        } break;
    }
}


//初始化CZURPlugin环境反馈，格式: {"id": 2, "error": 错误代码}
const  CZUR_ID_Initialize_Response =  (jsonObj) => {
    var error = jsonObj.error;
    switch  (error) {
        case 0: {
      
            console.log("初始化CZURPlugin成功");
            CZUR_ID_OpenDevice();
        } break;

        case 1: {
            console.log("初始化CZURPlugin失败 异常错误");
        } break;

        case 3: {
            console.log("初始化CZURPlugin失败 系统内存不足");
        } break;

        case 6: {
            console.log("无效的授权码");
        } break;
        case 9: {
            console.log("CZURPlugin环境已初始化");
        } break;
        case 9: {
            console.log("CZURPlugin环境已初始化");
        } break;

        case 42: {
            console.log("创建图像处理线程失败");
        } break;

        case 43: {
            console.log("字符集转换失败");
        } break;
    }
    m_cav_frame_handle()
}
// 关闭 WebSocket 连接
const disconnect_svc = () =>{
    ws_mc.value.close();
    // ws_sc.close();
    // ws_ir.close();
    ws_cmd.value.close();
}

onUnmounted(() => {
    disconnect_svc();
})
const CZUR_ID_ImageToPDFEx_Response = (jsonObj) => {
    var error = jsonObj.error;

        switch (error) {
            case 0: {
                console.log("合成PDF文件成功");
                submitRequest();
            } break;

            case 1: {
                
                console.log("异常错误，无法合成PDF");
            } break;

            case 3: {
                console.log("系统内存不足");
            } break;

            case 8: {
                console.log("CZURPlugin环境未初始化");
            } break;

            case 10: {
                
                console.log("设备不支持合成PDF功能");
            } break;

            case 13: {
                
                console.log("设备未连接，请将设备连接电脑");
            } break;

            case 18: {
                
                console.log("非法的图像文件格式，仅支持JPG、BMP、PNG格式");
            } break;

            case 33: {
                
                console.log("加载图像文件失败，请检查图像文件路径是否有效");
            } break;

            case 36: {
                
                console.log("保存PDF文件失败，请检查PDF文件路径是否有效或当前PDF文档是否被打开");
            } break;

            case 37: {
                
                console.log("存在的PDF文档存在密码保护，无法合成");
            } break;

            case 43: {
                
                console.log("字符集转换失败");
            } break;
        }
    }



// 提交
const handleSubmit = async () => {
    // 提交逻辑
    if(imagesList.value.length == 0){
        ElMessage.warning('请至少拍摄一张照片');
        return;
    }
    pdfName.value = savePath.value + new Date().getTime()+''+Math.floor(Math.random()*1000)+'.pdf';
    var jsonMsg = {
        id: 159,
        images: imagesList.value.map(item=>item.filePath),
        pdf: pdfName.value
    };
    submitLoad.value = true;
    ws_cmd.value.send(JSON.stringify(jsonMsg));
};

const submitRequest = async () => {
    let result = await projectCamera({
        id:route.query.id,
        paths: [pdfName.value]
    });
    submitLoad.value = false;
    if(result.errorCode == 0){
        ElMessage.success('提交成功');
        pdfName.value = "";
        imagesList.value = [];
        router.back();
    }
}    

const back = () => {
    router.back();
};
</script>

<style scoped lang="scss">
.highspeed-scanner-container{
    margin-top: 10px;
    height: max-content;
    gap: 15px; /* 子元素间距 */
    :deep(.el-card){
        flex: 0 0 auto;
        height: 70vh;
        .el-card__body{
            display: flex;
            height: 100%;
            box-sizing: border-box;
            flex-direction: column;
        }
        &+.el-card{
            flex: 1;
            margin-top: 0;
        }
        .title{
            flex: 0 0 auto;
            font-weight: 600;
            margin-bottom: 10px;
            font-size: 18px;
            .el-icon{
                margin-right: 5px;
            }
        }
        .fileView{
            flex: 1;
            position: relative;
            .emtry-view{
                position: absolute;
                top: 0;
                left: 0;
                z-index: 10;
                background: rgb(243, 244, 246);
                height: 100%;
                width: 100%;
                border-radius: var(--el-card-border-radius);
                .emtry-content{
                    text-align: center;
                    .el-icon{
                        color: #ccc;
                        font-size: 80px;
                        margin-bottom: 10px;
                    }
                    p{
                        font-size: 20px;

                    }
                }
            }
            canvas{
                width: 720px;
                height: 100%;
                overflow-clip-margin: content-box;
                overflow: clip;

            }
        }
        .ImgView-container{
            display: grid;
            gap: 10px;
            flex: 1;
            overflow: auto;
            .ImgView-emtry{
                height: 100%;
                font-size: 20px;
            }
            .PreviewImg{
                // cursor: pointer;
            }
            .Viewer-container{
                display: grid;
                grid:10px;
                grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));                
                grid-auto-rows: 90px; /* 统一每行的高度（避免图片高度不一致导致错位） */
                grid-auto-columns: 90px; /* 统一每列的宽度（避免图片宽度不一致导致错位） */
                .viewer-item{
                    border-radius: var(--el-card-border-radius);
                    overflow: hidden;
                    position: relative;
                    height: max-content;
                    width: 80px;
                    height: 80px;
                    .el-icon{
                        position: absolute;
                        top: 0;
                        right: 0;
                        font-size: 16px;
                        color: #fff;
                        cursor: pointer;
                        border-bottom-left-radius: var(--el-card-border-radius);
                        padding: 5px; 
                        display: none;
                        background: rgba(0,0,0,0.5);
                    }
                    &:hover{
                        .el-icon{
                            display: block;
                        }
                    }
                }
            }
        }
        .foot-btn{
            flex: 0 0 auto;
            margin-top: 10px;
        }
    }
}
</style>